package service

import (
	"context"
	"errors"
	"pmservice/db"
	"pmservice/graph/model"
)

func (s *Service) DoctorNew(ctx context.Context, input model.DoctorNew) (*model.Doctor, error) {
	hos := db.HospitalGet(s.Orm.DB, input.Hosuid)
	if hos == nil {
		return nil, errors.New("hos not found")
	}

	if db.DoctorExist(s.Orm.DB, input.Hosuid, "", input.Account) {
		return nil, errors.New("账号已被使用")
	}

	d, err := db.DoctorNew(s.Orm.DB, &input)
	if err != nil {
		return nil, err
	}

	return s.DoctorGet(ctx, d.UID, "")
}

func (s *Service) DoctorSave(ctx context.Context, uid string, input model.DoctorEdit) (bool, error) {
	doctor := db.DoctorGet(s.Orm.DB, uid)
	if doctor == nil {
		return false, errors.New("doctor not found")
	}

	if input.Account != nil && db.DoctorExist(s.Orm.DB, doctor.Hospital, uid, *input.Account) {
		return false, errors.New("account been used")
	}

	return db.DoctorSave(s.Orm.DB, doctor.Hospital, uid, &input), nil
}

func (s *Service) DoctorDelete(ctx context.Context, uid string) (bool, error) {
	return db.DoctorDel(s.Orm.DB, uid), nil
}

func (s *Service) DoctorResetPassword(ctx context.Context, uid string, oldpass string) (*model.DoctorResetPassResult, error) {
	newpass := "123456"
	if db.DoctorUpdatePassword(s.Orm.DB, uid, oldpass, newpass) {
		return &model.DoctorResetPassResult{
			Ok:      true,
			Newpass: &newpass,
		}, nil
	}

	return &model.DoctorResetPassResult{
		Ok: false,
	}, nil
}

func (s *Service) DoctorMonitorPoc(ctx context.Context, uid string, pocuid string) bool {
	return db.DoctorMonitorPoc(s.Orm.DB, uid, pocuid)
}

func (s *Service) DoctorUnmonitorPoc(ctx context.Context, uid string, pocuid string) bool {
	return db.DoctorUnmonitorPoc(s.Orm.DB, uid, pocuid)
}

func (s *Service) DoctorGetCompositeData(ctx context.Context, d *db.Doctor, prefix string) (*model.Doctor, error) {
	ret := d.ToGQL()
	if HasField(ctx, PrefixJoin(prefix, "hospital")) {
		ret.Hospital, _ = s.HospitalGet(ctx, d.Hospital, PrefixJoin(prefix, "hospital"))
	}
	if HasField(ctx, PrefixJoin(prefix, "pocs")) && len(d.Pocs) > 0 {
		pocs := make([]*model.PointOfCare, 0)
		for _, v := range d.Pocs {
			poc, _ := s.PocGet(ctx, v, PrefixJoin(prefix, "pocs"))
			pocs = append(pocs, poc)
		}
		ret.Pocs = pocs
	}

	return ret, nil
}

func (s *Service) DoctorGet(ctx context.Context, uid string, prefix string) (*model.Doctor, error) {
	d := db.DoctorGet(s.Orm.DB, uid)
	if d == nil {
		return nil, errors.New("doctor not found")
	}

	return s.DoctorGetCompositeData(ctx, d, prefix)
}

func (s *Service) DoctorLogin(ctx context.Context, account string, password string, prefix string) (*model.Doctor, error) {
	d := db.DoctorLogin(s.Orm.DB, account, password)
	if d == nil {
		return nil, errors.New("doctor login failed")
	}

	return s.DoctorGetCompositeData(ctx, d, prefix)
}

func (s *Service) DoctorGetByAccount(ctx context.Context, hosuid string, account string, prefix string) (*model.Doctor, error) {
	d := db.DoctorGetByAccount(s.Orm.DB, hosuid, account)
	if d == nil {
		return nil, errors.New("doctor not found")
	}

	return s.DoctorGetCompositeData(ctx, d, prefix)
}

func (s *Service) DoctorSearch(ctx context.Context, cond model.DoctorSearchCond, prefix string) (*model.DoctorSearchResult, error) {
	doctors, total := db.DoctorSearch(s.Orm.DB, cond)
	ret := model.DoctorSearchResult{
		Results: make([]*model.Doctor, 0),
		Total:   int(total),
	}

	for _, d := range doctors {
		doctor, _ := s.DoctorGetCompositeData(ctx, d, prefix)
		if doctor != nil {
			ret.Results = append(ret.Results, doctor)
		}
	}

	return &ret, nil
}
